From: iap10@labyrinth.cl.cam.ac.uk Date: Tue, 4 May 2004 16:24:33 +0000 (+0000) Subject: bitkeeper revision 1.886.1.1 (4097c3c1KkMumw6Mz5K7HxRBJXhY3Q) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~18232^2 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=7b2eb5ed360b124204f8a216bd1c0e3b6f04eaba;p=xen.git bitkeeper revision 1.886.1.1 (4097c3c1KkMumw6Mz5K7HxRBJXhY3Q) suspend/resume migration improvements --- diff --git a/tools/examples/xc_dom_create.py b/tools/examples/xc_dom_create.py index 382d580032..42c4289243 100755 --- a/tools/examples/xc_dom_create.py +++ b/tools/examples/xc_dom_create.py @@ -351,6 +351,18 @@ def make_domain(): else: print "Enabled PCI access (%d:%d:%d)." % \ (pci_bus,pci_dev,pci_func) + + if restore: + # send an unsolicited ARP reply for all non link-local IPs + gw=xenctl.utils.get_current_ipgw() + if gw == '': gw='255.255.255.255' + nlb=open('/proc/sys/net/ipv4/ip_nonlocal_bind','r').read()[0]=='1' + if not nlb: print >>open('/proc/sys/net/ipv4/ip_nonlocal_bind','w'), '1' + for ip in vfr_ipaddr: + if not xenctl.utils.check_subnet(ip,'169.254.0.0','255.255.0.0'): + print '/usr/sbin/arping -A -b -I eth0 -c 1 -s %s %s' % (ip,gw) + os.system('/usr/sbin/arping -A -b -I eth0 -c 1 -s %s %s' % (ip,gw)) + if not nlb: print >>open('/proc/sys/net/ipv4/ip_nonlocal_bind','w'), '0' if xc.domain_start( dom=id ) < 0: print "Error starting domain" diff --git a/tools/xc/lib/xc.h b/tools/xc/lib/xc.h index eb1b07da91..b27e446beb 100644 --- a/tools/xc/lib/xc.h +++ b/tools/xc/lib/xc.h @@ -58,15 +58,20 @@ int xc_shadow_control(int xc_handle, u64 domid, unsigned int sop); +#define XCFLAGS_VERBOSE 1 +#define XCFLAGS_LIVE 2 + int xc_linux_save(int xc_handle, u64 domid, - const char *state_file, - int verbose); + unsigned int flags, + int (*writerfn)(void *, const void *, size_t), + void *writerst ); int xc_linux_restore(int xc_handle, u64 domid, - const char *state_file, - int verbose, + unsigned int flags, + int (*readerfn)(void *, void *, size_t), + void *readerst, u64 *pdomid); int xc_linux_build(int xc_handle, diff --git a/tools/xc/lib/xc_linux_restore.c b/tools/xc/lib/xc_linux_restore.c index e27221281a..65ba875aef 100644 --- a/tools/xc/lib/xc_linux_restore.c +++ b/tools/xc/lib/xc_linux_restore.c @@ -45,25 +45,20 @@ static int get_pfn_list(int xc_handle, return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; } -static int checked_read(gzFile fd, void *buf, size_t count) -{ - int rc; - while ( ((rc = gzread(fd, buf, count)) == -1) && (errno == EINTR) ) - continue; - return rc == count; -} int xc_linux_restore(int xc_handle, u64 dom, - const char *state_file, - int verbose, + unsigned int flags, + int (*readerfn)(void *, void *, size_t), + void *readerst, u64 *pdomid) { dom0_op_t op; int rc = 1, i, j, n, k; unsigned long mfn, pfn, xpfn; unsigned int prev_pc, this_pc; - + int verbose = flags & XCFLAGS_VERBOSE; + /* Number of page frames in use by this Linux session. */ unsigned long nr_pfns; @@ -98,26 +93,10 @@ int xc_linux_restore(int xc_handle, mfn_mapper_t *region_mapper, *mapper_handle1; char *region_base; - /* The name and descriptor of the file that we are reading from. */ - int fd; - gzFile gfd; - mmu_t *mmu = NULL; int pm_handle = -1; - if ( (fd = open(state_file, O_RDONLY)) == -1 ) - { - PERROR("Could not open state file for reading"); - return 1; - } - - if ( (gfd = gzdopen(fd, "rb")) == NULL ) - { - ERROR("Could not allocate decompression state for state file"); - close(fd); - return 1; - } if ( mlock(&ctxt, sizeof(ctxt) ) ) { @@ -128,18 +107,18 @@ int xc_linux_restore(int xc_handle, } /* Start writing out the saved-domain record. */ - if ( !checked_read(gfd, signature, 16) || + if ( (*readerfn)(readerst, signature, 16) || (memcmp(signature, "LinuxGuestRecord", 16) != 0) ) { ERROR("Unrecognised state format -- no signature found"); goto out; } - if ( !checked_read(gfd, name, sizeof(name)) || - !checked_read(gfd, &nr_pfns, sizeof(unsigned long)) || - !checked_read(gfd, &ctxt, sizeof(ctxt)) || - !checked_read(gfd, shared_info, PAGE_SIZE) || - !checked_read(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) ) + if ( (*readerfn)(readerst, name, sizeof(name)) || + (*readerfn)(readerst, &nr_pfns, sizeof(unsigned long)) || + (*readerfn)(readerst, &ctxt, sizeof(ctxt)) || + (*readerfn)(readerst, shared_info, PAGE_SIZE) || + (*readerfn)(readerst, pfn_to_mfn_frame_list, PAGE_SIZE) ) { ERROR("Error when reading from state file"); goto out; @@ -250,7 +229,7 @@ int xc_linux_restore(int xc_handle, prev_pc = this_pc; } - if ( !checked_read(gfd, &j, sizeof(int)) ) + if ( (*readerfn)(readerst, &j, sizeof(int)) ) { ERROR("Error when reading from state file"); goto out; @@ -260,7 +239,7 @@ int xc_linux_restore(int xc_handle, if(j==0) break; // our work here is done - if ( !checked_read(gfd, region_pfn_type, j*sizeof(unsigned long)) ) + if ( (*readerfn)(readerst, region_pfn_type, j*sizeof(unsigned long)) ) { ERROR("Error when reading from state file"); goto out; @@ -306,21 +285,31 @@ int xc_linux_restore(int xc_handle, ppage = (unsigned long*) (region_base + i*PAGE_SIZE); - if ( !checked_read(gfd, ppage, PAGE_SIZE) ) + if ( (*readerfn)(readerst, ppage, PAGE_SIZE) ) { ERROR("Error when reading from state file"); goto out; } - if ( region_pfn_type[i] == L1TAB ) + switch( region_pfn_type[i] ) + { + case 0: + break; + + case L1TAB: { for ( k = 0; k < 1024; k++ ) { if ( ppage[k] & _PAGE_PRESENT ) { - if ( (xpfn = ppage[k] >> PAGE_SHIFT) >= nr_pfns ) + xpfn = ppage[k] >> PAGE_SHIFT; + +/*printf("L1 i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n", + i,pfn,mfn,k,ppage[k],xpfn);*/ + + if ( xpfn >= nr_pfns ) { - ERROR("Frame number in type %d page table is out of range. i=%d k=%d pfn=%d nr_pfns=%d",region_pfn_type[i],i,k,xpfn,nr_pfns); + ERROR("Frame number in type %d page table is out of range. i=%d k=%d pfn=%d nr_pfns=%d",region_pfn_type[i]>>29,i,k,xpfn,nr_pfns); goto out; } #if 0 @@ -335,15 +324,23 @@ int xc_linux_restore(int xc_handle, } } } - else if ( region_pfn_type[i] == L2TAB ) + break; + + case L2TAB: { for ( k = 0; k < (HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT); k++ ) { if ( ppage[k] & _PAGE_PRESENT ) { - if ( (xpfn = ppage[k] >> PAGE_SHIFT) >= nr_pfns ) + xpfn = ppage[k] >> PAGE_SHIFT; + +/*printf("L2 i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n", + i,pfn,mfn,k,ppage[k],xpfn);*/ + + if ( xpfn >= nr_pfns ) { - ERROR("Frame number in page table is out of range"); + ERROR("Frame number in type %d page table is out of range. i=%d k=%d pfn=%d nr_pfns=%d",region_pfn_type[i]>>29,i,k,xpfn,nr_pfns); + goto out; } #if 0 @@ -358,6 +355,12 @@ int xc_linux_restore(int xc_handle, } } } + break; + + default: + ERROR("Bogus page type %x page table is out of range. i=%d nr_pfns=%d",region_pfn_type[i],i,nr_pfns); + goto out; + } if ( add_mmu_update(xc_handle, mmu, (mfn< -#include #define BATCH_SIZE 1024 /* 1024 pages (4MB) at a time */ @@ -41,24 +40,18 @@ }) - -static int checked_write(gzFile fd, void *buf, size_t count) -{ - int rc; - while ( ((rc = gzwrite(fd, buf, count)) == -1) && (errno = EINTR) ) - continue; - return rc == count; -} - int xc_linux_save(int xc_handle, u64 domid, - const char *state_file, - int verbose) + unsigned int flags, + int (*writerfn)(void *, const void *, size_t), + void *writerst ) { dom0_op_t op; int rc = 1, i, j, k, n; unsigned long mfn; unsigned int prev_pc, this_pc; + int verbose = flags & XCFLAGS_VERBOSE; + //int live = flags & XCFLAGS_LIVE; /* state of the new MFN mapper */ mfn_mapper_t *mapper_handle1, *mapper_handle2; @@ -99,28 +92,6 @@ int xc_linux_save(int xc_handle, /* A temporary mapping, and a copy, of the guest's suspend record. */ suspend_record_t *p_srec, srec; - /* The name and descriptor of the file that we are writing to. */ - int fd; - gzFile gfd; - - int pm_handle = -1; - - if ( (fd = open(state_file, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 ) - { - PERROR("Could not open file for writing"); - return 1; - } - - /* - * Compression rate 1: we want speed over compression. We're mainly going - * for those zero pages, after all. - */ - if ( (gfd = gzdopen(fd, "wb1")) == NULL ) - { - ERROR("Could not allocate compression state for state file"); - close(fd); - return 1; - } if ( mlock(&ctxt, sizeof(ctxt) ) ) { @@ -324,14 +295,14 @@ int xc_linux_save(int xc_handle, goto out; } - if ( !checked_write(gfd, "LinuxGuestRecord", 16) || - !checked_write(gfd, name, sizeof(name)) || - !checked_write(gfd, &srec.nr_pfns, sizeof(unsigned long)) || - !checked_write(gfd, &ctxt, sizeof(ctxt)) || - !checked_write(gfd, live_shinfo, PAGE_SIZE) || - !checked_write(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) ) + if ( (*writerfn)(writerst, "LinuxGuestRecord", 16) || + (*writerfn)(writerst, name, sizeof(name)) || + (*writerfn)(writerst, &srec.nr_pfns, sizeof(unsigned long)) || + (*writerfn)(writerst, &ctxt, sizeof(ctxt)) || + (*writerfn)(writerst, live_shinfo, PAGE_SIZE) || + (*writerfn)(writerst, pfn_to_mfn_frame_list, PAGE_SIZE) ) { - ERROR("Error when writing to state file"); + ERROR("Error when writing to state file (1)"); goto out; } munmap(live_shinfo, PAGE_SIZE); @@ -401,15 +372,15 @@ int xc_linux_save(int xc_handle, } - if ( !checked_write(gfd, &j, sizeof(int) ) ) + if ( (*writerfn)(writerst, &j, sizeof(int) ) ) { - ERROR("Error when writing to state file"); + ERROR("Error when writing to state file (2)"); goto out; } - if ( !checked_write(gfd, pfn_type, sizeof(unsigned long)*j ) ) + if ( (*writerfn)(writerst, pfn_type, sizeof(unsigned long)*j ) ) { - ERROR("Error when writing to state file"); + ERROR("Error when writing to state file (3)"); goto out; } @@ -430,7 +401,8 @@ int xc_linux_save(int xc_handle, k++ ) { if ( !(page[k] & _PAGE_PRESENT) ) continue; - mfn = page[k] >> PAGE_SHIFT; + mfn = page[k] >> PAGE_SHIFT; + if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) ) { ERROR("Frame number in pagetable page is invalid"); @@ -439,11 +411,17 @@ int xc_linux_save(int xc_handle, page[k] &= PAGE_SIZE - 1; page[k] |= live_mfn_to_pfn_table[mfn] << PAGE_SHIFT; + /* + printf("L%d i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n", + pfn_type[j]>>29, + j,i,mfn,k,page[k],page[k]>>PAGE_SHIFT); + */ + } - if ( !checked_write(gfd, page, PAGE_SIZE) ) + if ( (*writerfn)(writerst, page, PAGE_SIZE) ) { - ERROR("Error when writing to state file"); + ERROR("Error when writing to state file (4)"); goto out; } @@ -451,9 +429,9 @@ int xc_linux_save(int xc_handle, } else { - if ( !checked_write(gfd, region_base + (PAGE_SIZE*j), PAGE_SIZE) ) + if ( (*writerfn)(writerst, region_base + (PAGE_SIZE*j), PAGE_SIZE) ) { - ERROR("Error when writing to state file"); + ERROR("Error when writing to state file (5)"); goto out; } } @@ -468,9 +446,9 @@ int xc_linux_save(int xc_handle, rc = 0; /* Zero terminate */ - if ( !checked_write(gfd, &rc, sizeof(int)) ) + if ( (*writerfn)(writerst, &rc, sizeof(int)) ) { - ERROR("Error when writing to state file"); + ERROR("Error when writing to state file (6)"); goto out; } @@ -485,16 +463,9 @@ out: (void)do_dom0_op(xc_handle, &op); } - gzclose(gfd); - if ( pfn_type != NULL ) free(pfn_type); - - /* On error, make sure the file is deleted. */ - if ( rc != 0 ) - unlink(state_file); return !!rc; - } diff --git a/tools/xc/lib/xc_private.h b/tools/xc/lib/xc_private.h index eaa301772d..3a2e3ea9f1 100644 --- a/tools/xc/lib/xc_private.h +++ b/tools/xc/lib/xc_private.h @@ -246,28 +246,4 @@ void * mfn_mapper_queue_entry(mfn_mapper_t *t, int offset, /*********************/ -#if 0 -typedef struct mfn_typer { - domid_t dom; - int xc_handle; - int max; - dom0_op_t op; -} mfn_typer_t; - - -mfn_typer_t *mfn_typer_init(int xc_handle, domid_t dom, int num ); - -void mfn_typer_queue_entry(mfn_typer_t *t, unsigned long mfn ); - -int mfn_typer_flush_queue(mfn_typer_t *t); -#endif - -int get_pfn_type_batch(int xc_handle, - u64 dom, int num, unsigned long *arr); - -unsigned int get_pfn_type(int xc_handle, - unsigned long mfn, - u64 dom); - - #endif /* __XC_PRIVATE_H__ */ diff --git a/tools/xc/py/Xc.c b/tools/xc/py/Xc.c index 322a20b411..0f073a21e6 100644 --- a/tools/xc/py/Xc.c +++ b/tools/xc/py/Xc.c @@ -6,6 +6,13 @@ #include #include +#include +#include +#include +#include +#include +#include +#include /* Needed for Python versions earlier than 2.3. */ #ifndef PyMODINIT_FUNC @@ -183,6 +190,7 @@ static PyObject *pyxc_linux_save(PyObject *self, u64 dom; char *state_file; int progress = 1; + unsigned int flags = 0; static char *kwd_list[] = { "dom", "state_file", "progress", NULL }; @@ -190,11 +198,124 @@ static PyObject *pyxc_linux_save(PyObject *self, &dom, &state_file, &progress) ) return NULL; - if ( xc_linux_save(xc->xc_handle, dom, state_file, progress) != 0 ) - return PyErr_SetFromErrno(xc_error); - - Py_INCREF(zero); - return zero; + if (progress) flags |= XCFLAGS_VERBOSE; + + if (strncmp(state_file,"tcp:", strlen("tcp:")) == 0) + { +#define max_namelen 64 + char server[max_namelen]; + char *port_s; + int port=777; + int sd = 0; + struct hostent *h; + struct sockaddr_in s; + int sockbufsize; + + int writerfn(void *fd, const void *buf, size_t count) + { + int tot = 0, rc; + do + { + rc = write( (int) fd, ((char*)buf)+tot, count-tot ); + if (rc<0) { perror("WRITE"); return rc; }; + tot += rc; + } + while(toth_addr, &(s.sin_addr.s_addr), h->h_length); + s.sin_port = htons(port); + if( connect(sd, (struct sockaddr *) &s, sizeof(s)) ) + goto serr; + + sockbufsize=128*1024; + if (setsockopt(sd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, sizeof sockbufsize) < 0) + { + goto serr; + } + + if ( xc_linux_save(xc->xc_handle, dom, flags, writerfn, (void*)sd) == 0 ) + { + close(sd); + Py_INCREF(zero); + return zero; + } + + serr: + + PyErr_SetFromErrno(xc_error); + if(sd)close(sd); + return NULL; + } + else + { + int fd; + gzFile gfd; + + int writerfn(void *fd, const void *buf, size_t count) + { + int rc; + while ( ((rc = gzwrite( (gzFile*)fd, (void*)buf, count)) == -1) && + (errno = EINTR) ) + continue; + return ! (rc == count); + } + + if (strncmp(state_file,"file:",strlen("file:")) == 0) + state_file += strlen("file:"); + + if ( (fd = open(state_file, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 ) + { + perror("Could not open file for writing"); + goto err; + } + + /* + * Compression rate 1: we want speed over compression. + * We're mainly going for those zero pages, after all. + */ + + if ( (gfd = gzdopen(fd, "wb1")) == NULL ) + { + perror("Could not allocate compression state for state file"); + close(fd); + goto err; + } + + + if ( xc_linux_save(xc->xc_handle, dom, flags, writerfn, gfd) == 0 ) + { + gzclose(gfd); + close(fd); + + Py_INCREF(zero); + return zero; + } + + err: + PyErr_SetFromErrno(xc_error); + if(gfd)gzclose(gfd); + if(fd)close(fd); + unlink(state_file); + + return NULL; + } + } static PyObject *pyxc_linux_restore(PyObject *self, @@ -206,6 +327,7 @@ static PyObject *pyxc_linux_restore(PyObject *self, char *state_file; int progress = 1; u64 dom; + unsigned int flags = 0; static char *kwd_list[] = { "dom", "state_file", "progress", NULL }; @@ -213,11 +335,149 @@ static PyObject *pyxc_linux_restore(PyObject *self, &dom, &state_file, &progress) ) return NULL; - if ( xc_linux_restore(xc->xc_handle, dom, state_file, progress, &dom) != 0 ) - return PyErr_SetFromErrno(xc_error); + if (progress) flags |= XCFLAGS_VERBOSE; + + if (strncmp(state_file,"tcp:", strlen("tcp:")) == 0) + { +#define max_namelen 64 + char server[max_namelen]; + char *port_s; + int port=777; + int ld = 0, sd = 0; + struct hostent *h; + struct sockaddr_in s, d, p; + socklen_t dlen, plen; + int sockbufsize; + int on = 1; + + int readerfn(void *fd, void *buf, size_t count) + { + int rc, tot = 0; + do { + rc = read( (int) fd, ((char*)buf)+tot, count-tot ); + if (rc<0) + { + perror("READ"); + return rc; + } + tot += rc; + } while( toth_addr, &(s.sin_addr.s_addr), h->h_length); + s.sin_addr.s_addr = htonl(INADDR_ANY); + s.sin_port = htons(port); + + if (setsockopt(ld, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) + goto serr; + + if( bind(ld, (struct sockaddr *) &s, sizeof(s)) ) + goto serr; + + if( listen(ld, 1) ) + goto serr; + + dlen=sizeof(struct sockaddr); + if( (sd = accept(ld, (struct sockaddr *) &d, &dlen )) < 0 ) + goto serr; + + plen = sizeof(p); + if (getpeername(sd, (struct sockaddr_in *) &p, + &plen) < 0) { + goto serr; + } + + printf("Accepted connection from %s\n", + inet_ntoa(p.sin_addr)); + + sockbufsize=128*1024; + if (setsockopt(sd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, sizeof sockbufsize) < 0) + { + goto serr; + } + + if ( xc_linux_restore(xc->xc_handle, dom, flags, readerfn, (void*)sd, &dom) == 0 ) + { + close(sd); + Py_INCREF(zero); + return zero; + } + + serr: + + PyErr_SetFromErrno(xc_error); + if(ld)close(ld); + if(sd)close(sd); + return NULL; + } + else + { + int fd; + gzFile gfd; + + int readerfn(void *fd, void *buf, size_t count) + { + int rc; + while ( ((rc = gzread( (gzFile*)fd, (void*)buf, count)) == -1) && + (errno = EINTR) ) + continue; + return ! (rc == count); + } + + if (strncmp(state_file,"file:",strlen("file:")) == 0) + state_file += strlen("file:"); + + if ( (fd = open(state_file, O_RDONLY)) == -1 ) + { + perror("Could not open file for writing"); + goto err; + } + + /* + * Compression rate 1: we want speed over compression. + * We're mainly going for those zero pages, after all. + */ + + if ( (gfd = gzdopen(fd, "rb")) == NULL ) + { + perror("Could not allocate compression state for state file"); + close(fd); + goto err; + } + + + if ( xc_linux_restore(xc->xc_handle, dom, flags, readerfn, gfd, &dom) == 0 ) + { + gzclose(gfd); + close(fd); + + Py_INCREF(zero); + return zero; + } + + err: + PyErr_SetFromErrno(xc_error); + if(gfd)gzclose(gfd); + if(fd)close(fd); + return NULL; + } - Py_INCREF(zero); - return zero; } static PyObject *pyxc_linux_build(PyObject *self, diff --git a/xenolinux-2.4.26-sparse/arch/xen/config.in b/xenolinux-2.4.26-sparse/arch/xen/config.in index 05d61a0314..16fa5e66d4 100644 --- a/xenolinux-2.4.26-sparse/arch/xen/config.in +++ b/xenolinux-2.4.26-sparse/arch/xen/config.in @@ -231,6 +231,8 @@ if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then # source drivers/input/Config.in else + define_bool CONFIG_NETDEVICES y + # # Block device driver configuration #